*** transform.c	Mon Oct 11 15:00:58 1993
--- transform.c.frac	Mon Oct 11 14:47:18 1993
***************
*** 305,310 ****
--- 305,418 ----
  	MatrixCopy(&ttmp, inverse);
  }
  
+ /* find eigenvalues of positive definite matrices, return FALSE is singular. */
+ int MatrixEigenvalues(trans, lambda)
+ RSMatrix *trans;
+ Float lambda[3];
+ {
+         Float a[3], maxval, a11, a12, a21, a22;
+         Float *A[3];
+ 
+         a[0] = fabs(trans->matrix[0][0]); maxval = a[0];
+         a[1] = fabs(trans->matrix[1][0]); if (a[1] > maxval) maxval = a[1];
+         a[2] = fabs(trans->matrix[2][0]); if (a[2] > maxval) maxval = a[2];
+   
+         if (maxval == a[0]) {
+                 A[0] = trans->matrix[0];
+                 A[1] = trans->matrix[1];
+                 A[2] = trans->matrix[2];
+         } else if (maxval == a[1]) {
+                 A[0] = trans->matrix[1];
+                 A[1] = trans->matrix[0];
+                 A[2] = trans->matrix[2];
+         } else {
+                 A[0] = trans->matrix[2];
+                 A[1] = trans->matrix[1];
+                 A[2] = trans->matrix[0];
+         }
+ 
+         lambda[0] = A[0][0];
+         if (lambda[0] == 0.) return FALSE;
+ 
+         a[1] = A[1][0] / lambda[0];
+         a[2] = A[2][0] / lambda[0];
+         a11 = A[1][1] - a[1] * A[0][1];        
+         a21 = A[2][1] - a[2] * A[0][1];        
+         a12 = A[1][2] - a[1] * A[0][2];        
+         a22 = A[2][2] - a[2] * A[0][2];        
+ 
+         if (fabs(a11) > fabs(a21)) {
+                 lambda[1] = a11;
+                 if (lambda[1] == 0.) return FALSE;
+                 lambda[2] = a22 - a21/a11 * a12;
+         } else {
+                 lambda[1] = a21;
+                 if (lambda[1] == 0.) return FALSE;
+                 lambda[2] = a12 - a11/a21 * a22;
+         }
+ 
+         if (lambda[2] == 0.) return FALSE;
+         return TRUE;
+ }
+ 
+ /* Lipschitz number for euclidian norm: largest scaling factor */
+ Float Lipschitz(lambda)
+ Float lambda[3];
+ {
+         Float maxlambda;
+ 
+         maxlambda = lambda[0];
+         if (lambda[1] > maxlambda) maxlambda = lambda[1];
+         if (lambda[2] > maxlambda) maxlambda = lambda[2];
+         return maxlambda;
+ }
+ 
+ /* returns TRUE if the three scaling factors are equal */
+ int Uniform(lambda)
+ Float lambda[3];
+ {
+         return (equal(lambda[0], lambda[1]) && equal(lambda[1], lambda[2]));
+ }
+ 
+ /* scaling factors */
+ int MatrixScaling(trans, lambda)
+ RSMatrix *trans;
+ Float lambda[3];
+ {
+         RSMatrix Q2;
+         int i;
+ 
+ /* Q-R decomposition: we are only interested in Q**2 */
+         Q2.matrix[0][0] = trans->matrix[0][0] * trans->matrix[0][0] +
+                           trans->matrix[0][1] * trans->matrix[0][1] +
+                           trans->matrix[0][2] * trans->matrix[0][2] ;
+         Q2.matrix[0][1] = trans->matrix[0][0] * trans->matrix[1][0] +
+                           trans->matrix[0][1] * trans->matrix[1][1] +
+                           trans->matrix[0][2] * trans->matrix[1][2] ;
+         Q2.matrix[0][2] = trans->matrix[0][0] * trans->matrix[2][0] +
+                           trans->matrix[0][1] * trans->matrix[2][1] +
+                           trans->matrix[0][2] * trans->matrix[2][2] ;
+         Q2.matrix[1][1] = trans->matrix[1][0] * trans->matrix[1][0] +
+                           trans->matrix[1][1] * trans->matrix[1][1] +
+                           trans->matrix[1][2] * trans->matrix[1][2] ;
+         Q2.matrix[1][2] = trans->matrix[1][0] * trans->matrix[2][0] +
+                           trans->matrix[1][1] * trans->matrix[2][1] +
+                           trans->matrix[1][2] * trans->matrix[2][2] ;
+         Q2.matrix[2][2] = trans->matrix[2][0] * trans->matrix[2][0] +
+                           trans->matrix[2][1] * trans->matrix[2][1] +
+                           trans->matrix[2][2] * trans->matrix[2][2] ;
+         Q2.matrix[1][0] = Q2.matrix[0][1];
+         Q2.matrix[2][0] = Q2.matrix[0][2];
+         Q2.matrix[2][1] = Q2.matrix[1][2];
+ 
+ /* scaling factors are square root of eigenvalues of Q**2 */
+         if (!MatrixEigenvalues(&Q2, lambda)) return FALSE;
+         lambda[0] = sqrt(lambda[0]);
+         lambda[1] = sqrt(lambda[1]);
+         lambda[2] = sqrt(lambda[2]);
+         return TRUE;
+ }
+ 
  /*
   * Apply a transformation to a point (translation affects the point).
   */
***************
*** 399,407 ****
  Ray *ray;
  RSMatrix *trans;
  {
  	PointTransform(&ray->pos, trans);
  	VecTransform(&ray->dir, trans);
! 	return VecNormalize(&ray->dir);
  }
  
  void
--- 507,519 ----
  Ray *ray;
  RSMatrix *trans;
  {
+         Float stretch;
  	PointTransform(&ray->pos, trans);
  	VecTransform(&ray->dir, trans);
! 
! 	stretch = VecNormalize(&ray->dir);
!         ray->stretch *= stretch;
!         return stretch;
  }
  
  void
***************
*** 433,437 ****
--- 545,552 ----
  {
  	TransCopy(list, result);
  	for (list = list->next; list; list = list->next)
+ /* it was: 
  		TransCompose(list, result, result);
+  * PhB made it: */
+ 		TransCompose(result, list, result);
  }
